//
//  AzirRPCService.Login.swift
//  Center_RPC
//
//  Created by 蒋晨成 on 2021/12/29.
//

import Center_Core_Model
import Foundation
import GRPC
public extension AzirRPCService {
    func appleAuth(
        authorizationCode: String,
        identityToken: String,
        email: String,
        userIdentifier: String,
        fullName: String?,
        complete: @escaping (Result<Azir_Gateway_AppleAuthResponse, Error>) -> Void
    ) {
        requestQueue.async {
            let client = Azir_Gateway_LoginClient(channel: self.connection, defaultCallOptions: self.callOptions(), interceptors: AzirClientInterceptorFactory())
            let call = client.appleAuth(
                .with {
                    $0.authorizationCode = authorizationCode
                    $0.identityToken = identityToken
                    $0.email = email
                    $0.userIdentifier = userIdentifier
                    $0.fullName = fullName ?? ""
                })
            call.response.whenComplete { result in self.resultQueue.async { complete(result) } }
            do {
                let status = try call.status.wait()
                self.logger.info("Call Status : \(status)")
            } catch {
                self.logger.error("Call Failed With Error : \(error)")
            }
        }
    }

    func wechatAuth(
        code: String,
        complete: @escaping (Result<Azir_Gateway_WechatAuthResponse, Error>) -> Void
    ) {
        requestQueue.async {
            let client = Azir_Gateway_LoginClient(channel: self.connection, defaultCallOptions: self.callOptions(), interceptors: AzirClientInterceptorFactory())
            let call = client.wechatAuth(
                .with {
                    $0.code = code
                })
            call.response.whenComplete { result in self.resultQueue.async { complete(result) } }
            do {
                let status = try call.status.wait()
                self.logger.info("Call Status : \(status)")
            } catch {
                self.logger.error("Call Failed With Error : \(error)")
            }
        }
    }

    func passwordLogin(
        accountName: String,
        password: String,
        complete: @escaping (Result<Azir_Gateway_UserLoginResponse, Error>) -> Void
    ) {
        requestQueue.async {
            let client = Azir_Gateway_LoginClient(channel: self.connection, defaultCallOptions: self.callOptions(), interceptors: AzirClientInterceptorFactory())
            let call = client.userLogin(
                .with {
                    $0.accountName = accountName
                    $0.password = password
                })
            call.response.whenComplete { result in self.resultQueue.async { complete(result) } }
            do {
                let status = try call.status.wait()
                self.logger.info("Call Status : \(status)")
            } catch {
                self.logger.error("Call Failed With Error : \(error)")
            }
        }
    }

    func changePassword(
        accountName: String,
        oldPassword: String,
        newPassword: String,
        complete: @escaping (Result<Azir_Gateway_ChangePasswordResponse, Error>) -> Void
    ) {
        requestQueue.async {
            let client = Azir_Gateway_LoginClient(channel: self.connection, defaultCallOptions: self.callOptions(), interceptors: AzirClientInterceptorFactory())
            let call = client.changePassword(
                .with {
                    $0.accountName = accountName
                    $0.oldPassword = oldPassword
                    $0.newPassword = newPassword
                })
            call.response.whenComplete { result in self.resultQueue.async { complete(result) } }
            do {
                let status = try call.status.wait()
                self.logger.info("Call Status : \(status)")
            } catch {
                self.logger.error("Call Failed With Error : \(error)")
            }
        }
    }

    func logout(complete: @escaping (Result<Azir_Gateway_LogoutResponse, Error>) -> Void) {
        requestQueue.async {
            let client = Azir_Gateway_LoginClient(channel: self.connection, defaultCallOptions: self.callOptions(), interceptors: AzirClientInterceptorFactory())
            let call = client.logout(Azir_Gateway_LogoutRequest())
            call.response.whenComplete { result in self.resultQueue.async { complete(result) } }
            do {
                let status = try call.status.wait()
                self.logger.info("Call Status : \(status)")
            } catch {
                self.logger.error("Call Failed With Error : \(error)")
            }
        }
    }

    enum LoginError: Error {
        case todo
    }

    func logoff(complete: @escaping (Result<Azir_Gateway_LogoutResponse, Error>) -> Void) {
//        requestQueue.async {
//            let client = Azir_Gateway_LoginClient(channel: self.connection, defaultCallOptions: self.callOptions(), interceptors: AzirClientInterceptorFactory())
//            let call = client.logout(Azir_Gateway_LogoutRequest())
//            call.response.whenComplete { result in self.resultQueue.async { complete(result) } }
//            do {
//                let status = try call.status.wait()
//                self.logger.info("Call Status : \(status)")
//            } catch {
//                self.logger.error("Call Failed With Error : \(error)")
//            }
//        }
        logger.error("Call Failed To Do")
        complete(.failure(LoginError.todo))
    }

    func mobileAuth(
        mobile: String,
        code: String,
        complete: @escaping (Result<Azir_Gateway_MobileAuthResponse, Error>) -> Void
    ) {
        requestQueue.async {
            let client = Azir_Gateway_LoginClient(channel: self.connection, defaultCallOptions: self.callOptions(), interceptors: AzirClientInterceptorFactory())
            let call = client.mobileAuth(
                .with {
                    $0.mobile = mobile
                    $0.code = code
                })
            call.response.whenComplete { result in self.resultQueue.async { complete(result) } }
            do {
                let status = try call.status.wait()
                self.logger.info("Call Status : \(status)")
            } catch {
                self.logger.error("Call Failed With Error : \(error)")
            }
        }
    }

    func sendSMS(
        mobile: String,
        complete: @escaping (Result<Azir_Gateway_SendSMSResponse, Error>) -> Void
    ) {
        requestQueue.async {
            let client = Azir_Gateway_LoginClient(channel: self.connection, defaultCallOptions: self.callOptions(), interceptors: AzirClientInterceptorFactory())
            let call = client.sendSMS(
                .with {
                    $0.mobile = mobile
                })
            call.response.whenComplete { result in self.resultQueue.async { complete(result) } }
            do {
                let status = try call.status.wait()
                self.logger.info("Call Status : \(status)")
            } catch {
                self.logger.error("Call Failed With Error : \(error)")
            }
        }
    }
}
